package com.example.statemachine.service;

import com.example.statemachine.entity.Task;
import com.example.statemachine.core.EventEnum;
import com.example.statemachine.core.StateEnum;
import com.example.statemachine.core.StateMachineContext;
import com.example.statemachine.support.annotation.StateMachine;
import com.example.statemachine.support.annotation.StateTransition;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Component
@StateMachine(entityType = Task.class)
public class TaskStateMachine {

    @StateTransition(source = StateEnum.INIT, event = EventEnum.START_PROCESS,
            target = StateEnum.PROCESSING, description = "开始处理任务")
    @Transactional
    public Task startProcess(Task task, StateMachineContext context) {
        log.info("开始处理任务: {}, 操作人: {}", task.getTaskNo(), context.getOperator());

        // 更新任务状态
        task.setStatus(StateEnum.PROCESSING);

        // 可以在这里执行其他业务逻辑，比如发送通知等
        if (context.getExtraParams() != null) {
            String assignee = (String) context.getExtraParams().get("assignee");
            if (assignee != null) {
                task.setAssignee(assignee);
            }
        }

        return task;
    }

    @StateTransition(source = StateEnum.PROCESSING, event = EventEnum.SUBMIT_APPROVAL,
            target = StateEnum.APPROVING, description = "提交审批")
    @Transactional
    public Task submitApproval(Task task, StateMachineContext context) {
        log.info("提交任务审批: {}, 操作人: {}", task.getTaskNo(), context.getOperator());

        task.setStatus(StateEnum.APPROVING);

        if (context.getExtraParams() != null) {
            String approver = (String) context.getExtraParams().get("approver");
            if (approver != null) {
                task.setApprover(approver);
            }
        }

        return task;
    }

    @StateTransition(source = StateEnum.APPROVING, event = EventEnum.APPROVE,
            target = StateEnum.COMPLETED, description = "审批通过")
    @Transactional
    public Task approve(Task task, StateMachineContext context) {
        log.info("审批通过任务: {}, 操作人: {}", task.getTaskNo(), context.getOperator());
        task.setStatus(StateEnum.COMPLETED);
        return task;
    }

    @StateTransition(source = StateEnum.APPROVING, event = EventEnum.REJECT,
            target = StateEnum.REJECTED, description = "审批拒绝")
    @Transactional
    public Task reject(Task task, StateMachineContext context) {
        log.info("审批拒绝任务: {}, 操作人: {}", task.getTaskNo(), context.getOperator());
        task.setStatus(StateEnum.REJECTED);

        if (context.getExtraParams() != null) {
            String rejectReason = (String) context.getExtraParams().get("rejectReason");
            if (rejectReason != null) {
                context.setRemark(rejectReason);
            }
        }

        return task;
    }

    @StateTransition(source = StateEnum.PROCESSING, event = EventEnum.MODIFY,
            target = StateEnum.PROCESSING, description = "修改任务信息")
    @Transactional
    public Task modify(Task task, StateMachineContext context) {
        log.info("修改任务信息: {}, 操作人: {}", task.getTaskNo(), context.getOperator());

        // 状态不变，只更新其他信息
        if (context.getExtraParams() != null) {
            String assignee = (String) context.getExtraParams().get("assignee");
            if (assignee != null) {
                task.setAssignee(assignee);
            }
            String description = (String) context.getExtraParams().get("description");
            if (description != null) {
                task.setDescription(description);
            }
        }

        return task;
    }

    @StateTransition(source = StateEnum.REJECTED, event = EventEnum.START_PROCESS,
            target = StateEnum.PROCESSING, description = "重新开始处理")
    @Transactional
    public Task restartProcess(Task task, StateMachineContext context) {
        log.info("重新开始处理任务: {}, 操作人: {}", task.getTaskNo(), context.getOperator());
        task.setStatus(StateEnum.PROCESSING);
        return task;
    }
}